#include "opecv_img_data.h"
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace std;
using namespace cv;

void doOpencvImgData1()
{
	Mat img = imread("test.jpg", 1); 
	if (img.empty())
	{
		cout << "fail to read image" << endl;
		return ;
	}
	Mat img1 = img.clone();
	int div = 64;

	/* 方法1：用指针访问 */
	//多通道访问法1
	int rows = img1.rows;
	int cols = img1.cols; 
	for (int i = 0; i < rows; i++)
	{
		//uchar* p = img1.ptr<uchar>(i);  //获取第i行的首地址
		for (int j = 0; j < cols; j++)
		{
			//在这里操作具体元素
			uchar *p = img1.ptr<uchar>(i, j);
			p[0] = p[0] / div*div + div / 2;
			p[1] = p[1] / div*div + div / 2;
			p[2] = p[2] / div*div + div / 2;
		}
	}

	imshow("lean", img1);


	//多通道访问法2
	Mat img3 = img.clone();
	int channels = img3.channels(); //获取通道数
	int rows3 = img3.rows;
	int cols3 = img3.cols* channels; //注意，是列数*通道数
	for (int i = 0; i < rows3; i++)
	{
		uchar* p = img3.ptr<uchar>(i);  //获取第i行的首地址
		for (int j = 0; j < cols3; j++)
		{
			//在这里操作具体元素
			p[j] = p[j] / div*div + div / 2;
			p[j+1] = p[j+1] / div*div + div / 2;
			p[j+2] = p[j+2] / div*div + div / 2;
		}
	}

	imshow("lean3", img3);

	//单通道图像
	Mat img2 = img.clone();
	cvtColor(img2, img2, COLOR_BGR2GRAY);
	for (int i = 0; i < img2.rows; i++)
	{
		uchar* p = img2.ptr<uchar>(i);  //获取第i行的首地址
		for (int j = 0; j < img2.cols; j++)
		{
			//在这里操作具体元素
			p[j] = p[j] / div*div + div / 2;
		}
	}

	imshow("lean2", img2);
	waitKey(0);
}


void doOpencvImgData2()
{
	Mat img = imread("test.jpg",1); //载入灰度图
	Mat img1 = img.clone();
	int div = 64;
	/* 方法2：用迭代器访问 */

	/******************多通道的可以这么写***************/
	Mat_<Vec3b>::iterator it = img1.begin<Vec3b>();  //获取起始迭代器
	Mat_<Vec3b>::iterator it_end = img1.end<Vec3b>();  //获取结束迭代器
	for (; it != it_end; it++)
	{
		//在这里分别访问每个通道的元素
		(*it)[0] = (*it)[0] / div*div + div / 2;
		(*it)[1] = (*it)[1] / div*div + div / 2;
		(*it)[1] = (*it)[1] / div*div + div / 2;
	}

	imshow("lean", img1);


	/******************单通道的可以这么写***************/
	Mat img2;
	cvtColor(img, img2, COLOR_RGB2GRAY); //转化为单通道灰度图

	Mat_<uchar>::iterator it2 = img2.begin<uchar>();  //获取起始迭代器
	Mat_<uchar>::iterator it_end2 = img2.end<uchar>();  //获取结束迭代器
	for (; it2 != it_end2; it2++)
	{
            //在这里分别访问每个通道的元素
            *it2 = *it2 / div*div + div / 2;
	}
	imshow("lena2", img2);

	waitKey(0);
}



void doOpencvImgData3()
{
	Mat img = imread("test.jpg",1); 
	Mat img1 = img.clone();
	int div = 64;
	/* 方法3：用at访问 */

	/****************访问多通道元素*********************/
	int rows = img1.rows;
	int cols = img1.cols;
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			//在这里访问每个通道的元素,注意，成员函数at(int y,int x)的参数
			img1.at<Vec3b>(i,j)[0] = img1.at<Vec3b>(i, j)[0] / div*div + div / 2;
			img1.at<Vec3b>(i, j)[1] = img1.at<Vec3b>(i, j)[1] / div*div + div / 2;
			img1.at<Vec3b>(i, j)[2] = img1.at<Vec3b>(i, j)[2] / div*div + div / 2;

		}
	}

	imshow("lena", img1);

	/****************访问单通道元素*********************/
	Mat img2;
	cvtColor(img, img2, COLOR_RGB2GRAY);

	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			//在这里访问每个通道的元素,注意，成员函数at(int y,int x)的参数
			img2.at<uchar>(i, j) = img2.at<uchar>(i, j) / div*div + div / 2;
		}
	}

	imshow("lena2", img2);

	waitKey(0);
}



void doOpencvImgData4()
{
	/*访问单通道元素*/
	IplImage* img = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1); //单通道图像
	CvScalar s;
	double tmp;
	for (int i = 0; i < img->height; i++)
	{
		for (int j = 0; j < img->width; j++)
		{
			//可以在这里访问元素
			tmp = cvGet2D(img, i, j).val[0];
			cvSet2D(img, i, j, cvScalar(255.0));  //第三个参数是要设置的值
		}
	}
	cvShowImage("img", img);


	/*访问多通道元素*/
	IplImage* img2 = cvCreateImage(cvSize(640, 480), IPL_DEPTH_32F, 3);
	double tmpb, tmpg, tmpr;
	for (int i = 0; i < img->height; i++)
	{
		for (int j = 0; j < img->width; j++)
		{
			tmpb = cvGet2D(img, i, j).val[0];
			tmpg = cvGet2D(img, i, j).val[1];
			tmpr = cvGet2D(img, i, j).val[2];

			cvSet2D(img2, i, j, cvScalar(255.0));  //第三个参数是要设置的值,三个通道一起设置
		}
	}
	cvShowImage("img2", img2);

	waitKey(0);
}

void doOpencvImgData5()
{
	/*访问多通道元素*/
	IplImage* img = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3);
	uchar* data = (uchar *)img->imageData;
	int step = img->widthStep / sizeof(uchar);
	int channels = img->nChannels;
	uchar b, g, r;
	for (int i = 0; i < img->height; i++)
	{
		for (int j = 0; j < img->width; j++)
		{
			//获得元素的值
			b = data[i*step + j*channels + 0];
			g = data[i*step + j*channels + 1];
			r = data[i*step + j*channels + 2];

			//修改元素的值
			data[i*step + j*channels + 0] = 255;
		}
	}

	cvShowImage("img", img);


	/*访问单通道元素*/
	IplImage* img2 = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1);
	uchar* data2 = (uchar *)img2->imageData;
	int step2 = img2->widthStep / sizeof(uchar);
	uchar v;
	for (int i = 0; i < img2->height; i++)
	{
		for (int j = 0; j < img2->width; j++)
		{
			//获得元素的值
			v = data2[i*step2 + j];

			//修改元素的值
			data2[i*step2 + j] = 255;
		}
	}

	cvShowImage("img2", img2);
	waitKey(0);
}

